using System.Security.Cryptography;
using System.Text;
using Aliyun.OSS;
using Aliyun.OSS.Common;

namespace StudyCompanion.Core.Aliyun;

public class OSS
{
    /// <summary>
    ///     获取阿里云 accessKeyId
    /// </summary>
    private const string accessKeyId = "LTAI5tHxxnBAA6oFVBJPxgef";

    /// <summary>
    ///     获取阿里云 accessKeySecret
    /// </summary>
    private const string accessKeySecret = "c2LM5CeMvxt4KweOh93ttj2NXKyGjz";

    /// <summary>
    ///     endpoint
    /// </summary>
    private const string endpoint = "oss-cn-zhangjiakou.aliyuncs.com";

    /// <summary>
    ///     bucket
    /// </summary>
    private const string bucket = "singular-point";

    /// <summary>
    ///     oss私有读
    /// </summary>
    /// <param name="path">oss文件路径</param>
    /// <param name="bucketName">桶名称</param>
    /// <returns></returns>
    /// <exception cref="OssException"></exception>
    /// <exception cref="Exception"></exception>
    public static string SignUrl(string path, string bucketName)
    {
        var objectName = $"{path}";
        var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
        try
        {
            var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Get)
            {
                Expiration = DateTime.Now.AddMinutes(60) //有效期10分钟
            };
            return client.GeneratePresignedUri(req).ToString();
        }
        catch (OssException ex)
        {
            throw ex;
        }
    }

    /// <summary>
    ///     OSS上传签名
    /// </summary>
    /// <param name="prefix">用户上传文件时指定的前缀</param>
    /// <returns></returns>
    public static object UploadSign(string prefix)
    {
        var host = $"https://{bucket}.{endpoint}";
        OssClient client = new(host, accessKeyId, accessKeySecret);
        var ex = DateTime.Now.AddSeconds(60);

        PolicyConditions policyConds = new();
        policyConds.AddConditionItem(PolicyConditions.CondContentLengthRange, 0L, 1048576000L);
        if (!string.IsNullOrEmpty(prefix))
            policyConds.AddConditionItem(MatchMode.StartWith, PolicyConditions.CondKey, prefix);

        var postPolicy = client.GeneratePostPolicy(ex, policyConds);
        var binaryData = Encoding.UTF8.GetBytes(postPolicy);
        var policy = Convert.ToBase64String(binaryData);

        var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(accessKeySecret));
        var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(policy));
        var signature = Convert.ToBase64String(hashBytes);
        return new
        {
            AccessKeyId = accessKeyId,
            Policy = policy,
            Signature = signature,
            Dir = prefix,
            Host = host,
            Expire = ex.ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).Seconds
        };
    }
    
    /// <summary>
    ///     OSS签名
    /// </summary>
    /// <param name="dir">用户上传文件时指定的前缀</param>
    /// <returns></returns>
    public static OssSign OssSign(string dir = "")
    {
        var host = $"https://lbuddy-routine.{endpoint}";
        var client = new OssClient(host, accessKeyId, accessKeySecret);

        var ex = DateTime.Now.AddSeconds(60);

        var policyConds = new PolicyConditions();
        policyConds.AddConditionItem(PolicyConditions.CondContentLengthRange, 0L, 1048576000L);
        policyConds.AddConditionItem(MatchMode.StartWith, PolicyConditions.CondKey, dir);

        var postPolicy = client.GeneratePostPolicy(ex, policyConds);
        var binaryData = Encoding.UTF8.GetBytes(postPolicy);
        var policy = Convert.ToBase64String(binaryData);

        var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(accessKeySecret));
        var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(policy));
        var Signature = Convert.ToBase64String(hashBytes);
        return new OssSign
        {
            AccessKeyId = accessKeyId,
            Policy = policy,
            Signature = Signature,
            Dir = dir,
            Host = host,
            Expire = ex.ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).Seconds
        };
    }
}
public class OssSign
{
    /// <summary>
    /// </summary>
    public string AccessKeyId { get; set; }

    /// <summary>
    /// </summary>
    public string Policy { get; set; }

    /// <summary>
    /// </summary>
    public string Signature { get; set; }

    /// <summary>
    ///     路径
    /// </summary>
    public string Dir { get; set; }

    /// <summary>
    /// </summary>
    public string Host { get; set; }

    /// <summary>
    ///     时间戳
    /// </summary>
    public int Expire { get; set; }
}